﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Web;

namespace LO1200.Web.UI
{
    public class TwitterFeedHandler : IHttpHandler
    {
        public static IEnumerable<Tweet> GetTweets(string query, int maxResults)
        {
            return GetTweets(query, TwitterLanguage.Any, maxResults, -1);
        }
        public static IEnumerable<Tweet> GetTweets(string query, TwitterLanguage language, int maxResults, long lastID)
        {
            // TODO: change this to use a DB or some other data source.

            if (maxResults <= 0 || maxResults > 100) throw new ArgumentException("Maximum results to return must be between 1 and 100.", "maxResults");

            var searchString = new StringBuilder();
            searchString.AppendFormat("http://search.twitter.com/search.atom?q={0}&result_type=recent&rpp={1}", HttpUtility.UrlEncode(query), maxResults);
            if (language != TwitterLanguage.Any)
            {
                // TODO: make this more flexible, tag the enum entry with an attribute instead.
                var languageString = "";
                switch(language)
                {
                    case TwitterLanguage.English:
                        languageString = "en";
                        break;
                }
                searchString.AppendFormat("&lang={0}", languageString);
            }

            var feed = Argotic.Syndication.AtomFeed.Create(new Uri(searchString.ToString()));

            // TODO: this must be a bit more robust.
            // TODO: extract geo locational data from the tweet if it exists.
            var result = new List<Tweet>();
            foreach(var entry in feed.Entries)
            {
                var entryID = entry.Id.Uri.ToString();
                long id;
                if (!long.TryParse(entryID.Substring(entryID.LastIndexOf(':') + 1), out id)) id = 0;
                if (lastID != -1 && id <= lastID) break;
                var tweet = new Tweet(id, entry.Authors[0].Name, entry.PublishedOn, entry.Content.Content);
                result.Add(tweet);
            }
            return result.ToArray();
        }
        
        /// <summary>
        /// Gets a value indicating whether another request can use the <see cref="T:System.Web.IHttpHandler"/> instance.
        /// </summary>
        /// <returns>
        /// true if the <see cref="T:System.Web.IHttpHandler"/> instance is reusable; otherwise, false.
        /// </returns>
        public bool IsReusable
        {
            get { return true; }
        }

        /// <summary>
        /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref="T:System.Web.IHttpHandler"/> interface.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpContext"/> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests. </param>
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";

            var query = context.Request["q"];
            long lastID;
            if (!long.TryParse(context.Request["lastID"], out lastID)) lastID = -1;
            int max;
            if (!int.TryParse(context.Request["max"], out max)) max = 10;

            var tweets = GetTweets(query, TwitterLanguage.Any, max, lastID);
            var serializer = new DataContractJsonSerializer(tweets.GetType());
            serializer.WriteObject(context.Response.OutputStream, tweets);
        }
    }
}
